package com.yicong.ants.manager;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import com.blankj.utilcode.util.ToastUtils;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.cchao.simplelib.LibCore;
import com.cchao.simplelib.core.AndroidHelper;
import com.cchao.simplelib.core.CollectionHelper;
import com.cchao.simplelib.core.GlideApp;
import com.cchao.simplelib.core.ImageLoader;
import com.cchao.simplelib.core.RxHelper;
import com.cchao.simplelib.core.UiHelper;
import com.cchao.simplelib.util.FileUtils;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.engine.CompressFileEngine;
import com.luck.picture.lib.engine.CropFileEngine;
import com.luck.picture.lib.engine.ImageEngine;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener;
import com.luck.picture.lib.interfaces.OnPermissionsInterceptListener;
import com.luck.picture.lib.interfaces.OnRequestPermissionListener;
import com.luck.picture.lib.interfaces.OnResultCallbackListener;
import com.luck.picture.lib.utils.DateUtils;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.yalantis.ucrop.UCrop;
import com.yalantis.ucrop.UCropImageEngine;
import com.yicong.ants.R;
import com.yicong.ants.bean.base.RespBean;
import com.yicong.ants.bean.common.UploadFile;
import com.yicong.ants.bean.common.UploadImageBean;
import com.yicong.ants.manager.holder.GlideRoundTransform;
import com.yicong.ants.manager.http.RetrofitHelper;
import com.yicong.ants.manager.loader.GlideEngine2;
import com.yicong.ants.utils.BitmapUtils;
import com.yicong.ants.utils.PermissionsChecker;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.functions.Consumer;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import top.zibin.luban.Luban;
import top.zibin.luban.OnNewCompressListener;
import top.zibin.luban.OnRenameListener;

/**
 * @author cchao
 * @version 2019-07-30.
 */
public class ImageHelper extends ImageLoader {

    public static final String mCompressVideoDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + LibCore.getContext().getPackageName();
    public static final String mCompressOutputPath = ImageHelper.mCompressVideoDir + "/output.mp4";

    public static void loadImageRound(ImageView imageView, String path, int round, @DrawableRes int placeholder) {
        if (AndroidHelper.isContextDestroyed(imageView.getContext())) {
            return;
        }

        GlideApp.with(imageView.getContext())
                .load(path)
                .transform(new GlideRoundTransform(round))
                .placeholder(placeholder)
                .into(imageView);
    }

    public static void loadImageRound(ImageView imageView, String path, int round, @DrawableRes int placeholder, int frameColor, int width) {
        if (AndroidHelper.isContextDestroyed(imageView.getContext())) {
            return;
        }
        GlideApp.with(imageView.getContext())
                .load(path)
                .transform(new GlideRoundTransform(round, ContextCompat.getColor(imageView.getContext(), frameColor), width))
                .placeholder(placeholder)
                .into(imageView);
    }

    public static void loadImageRound(ImageView imageView, String path) {
        loadImageRound(imageView, path, 10, R.drawable.place_holder);
    }

    public static void loadImageRound(ImageView imageView, String path, int round) {
        loadImageRound(imageView, path, round, R.drawable.place_holder);
    }

    public static void uploadAvatar(CompositeDisposable compositeDisposable, UploadImageBean bean
            , Consumer<RespBean<String>> respConsumer, Consumer<? super Throwable> error) {

        File file = new File(bean.getLocalUri());
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        // api 上传
        compositeDisposable.add(RetrofitHelper.getApis().updateAvatar(body)
                .compose(RxHelper.toMain())
                .subscribe(respBean -> {
                    if (respBean.isCodeFail()) {
                        UiHelper.showToast(respBean.getMsg());
                        return;
                    }

                    if (respConsumer != null) {
                        respConsumer.accept(respBean);
                    }
                }, error));
    }

    /**
     * 上传图片
     */
    public static void uploadFile(CompositeDisposable compositeDisposable, String localUri
            , Consumer<RespBean<UploadFile>> respConsumer, Consumer<? super Throwable> error) {

        File file = new File(localUri);
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        // api 上传
        compositeDisposable.add(RetrofitHelper.getApis().uploadFile(body)
                .compose(RxHelper.toMain())
                .subscribe(respBean -> {
                    if (respBean.isCodeFail()) {
                        UiHelper.showToast(respBean.getMsg());
                        return;
                    }

                    if (respConsumer != null) {
                        respConsumer.accept(respBean);
                    }
                }, error));
    }

    /**
     * 上传图片
     */
    public static void uploadImage(CompositeDisposable compositeDisposable, String localUri
            , Consumer<RespBean<String>> respConsumer, Consumer<? super Throwable> error) {

        File file = new File(localUri);
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        // api 上传
        compositeDisposable.add(RetrofitHelper.getApis().uploadImage(body)
                .compose(RxHelper.toMain())
                .subscribe(respBean -> {
                    if (respBean.isCodeFail()) {
                        UiHelper.showToast(respBean.getMsg());
                        return;
                    }

                    if (respConsumer != null) {
                        respConsumer.accept(respBean);
                    }
                }, error));
    }

    public static void setLayoutParamsWh(View view, int width, int ratioW, int ratioH) {
        int height = (int) (width * 1.0f / ratioW * ratioH);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(width, height);
        view.setLayoutParams(layoutParams);
    }

    public static void uploadImage(CompositeDisposable compositeDisposable, String type, UploadImageBean bean
            , Consumer<RespBean<UploadImageBean>> respConsumer, Consumer<? super Throwable> error) {

        File file = new File(bean.getLocalUri());
        RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);
        // api 上传
        compositeDisposable.add(RetrofitHelper.getApis().uploadImage(type, body)
                .compose(RxHelper.toMain())
                .subscribe(respBean -> {
                    if (respBean.isCodeFail()) {
                        UiHelper.showToast(respBean.getMsg());
                        return;
                    }

                    bean.setAbsoluteUrl(respBean.getData().getAbsoluteUrl())
                            .setRelativeUrl(respBean.getData().getRelativeUrl());

                    if (respConsumer != null) {
                        respConsumer.accept(respBean);
                    }
                }, error));
    }

    public static void addImage(Activity activity, int max, RecyclerView mRecycler, BaseQuickAdapter<LocalMedia, BaseViewHolder> adapter) {
        List<LocalMedia> mMediaList = adapter.getData();
        if (mMediaList.size() >= 1 && mMediaList.get(0).getMimeType().contains("video")) {
            UiHelper.showToast("只允许上传一个视频");
            return;
        }

        int pictureMimeType = SelectMimeType.ofAll();
        if (mMediaList.size() > max && mMediaList.get(0).getMimeType().contains("image")) {
            UiHelper.showToast("只允许上传" + max + "张图片");
            return;
        }

        if (mMediaList.size() > 1 && mMediaList.get(0).getMimeType().contains("image")) {
            pictureMimeType = SelectMimeType.ofImage();
        }
        PictureSelector.create(activity)
                .openGallery(pictureMimeType)
                .setCropEngine(new ImageFileCropEngine())
                .setMaxVideoSelectNum(1)
                .setMaxSelectNum(max - (mMediaList.size() - 1))
                .isPreviewVideo(true)
                .setCompressEngine(new ImageFileCompressEngine())
                .setImageEngine(GlideEngine2.createGlideEngine())
                .forResult(new OnResultCallbackListener<LocalMedia>() {
                    @Override
                    public void onResult(ArrayList<LocalMedia> result) {
                        if (CollectionHelper.isEmpty(result)) {
                            return;
                        }

                        List<LocalMedia> list = new ArrayList<>();
                        for (LocalMedia media : result) {
                            if (media != null) {
                                list.add(media);
                            }
                        }
                        if (CollectionHelper.isNotEmpty(list)) {
                            adapter.addData(0, list);
//                        if (adapter.getData().size() > max || list.get(0).getMimeType().contains("video")) {
//                            adapter.remove(adapter.getData().size() - 1);
//                        }
                        }
//                    run.run();
                    }

                    @Override
                    public void onCancel() {
                        // 取消
                    }
                });
    }

    public interface SelectCallBack {
        void selected(List<LocalMedia> localMediaList);
    }

    public static void takeImage(Activity activity, SelectCallBack selectCallBack) {
        PictureSelector.create(activity)
                .openGallery(SelectMimeType.ofImage())
                .setMaxSelectNum(1)
                .setMinSelectNum(1)
                .setCropEngine(new ImageFileCropEngine())
                .isPreviewVideo(true)
                .setCompressEngine(new ImageFileCompressEngine())
                .setImageEngine(GlideEngine2.createGlideEngine())
                .setPermissionsInterceptListener(new OnPermissionsInterceptListener() {
                    @Override
                    public void requestPermission(Fragment fragment, String[] permissionArray, OnRequestPermissionListener call) {
                        if (PermissionsChecker.checkPermissions(fragment.getContext(), permissionArray)) {
                            call.onCall(permissionArray, true);
                            return;
                        }
                        if (permissionArray[0].equals(Manifest.permission.CAMERA)) {
                            UiHelper.showConfirmDialog(fragment.getActivity(), "权限申请", "需要获取“相机”权限，开启后将可以用于照片或视频的拍摄功能",
                                    (dialog, which) -> {
                                        switch (which) {
                                            case DialogInterface.BUTTON_POSITIVE:
                                                new RxPermissions(fragment.getActivity())
                                                        .request(permissionArray)
                                                        .subscribe(aBoolean -> call.onCall(permissionArray, aBoolean));
                                                break;
                                            case DialogInterface.BUTTON_NEGATIVE:
                                                ToastUtils.showLong("没有权限，无法拍摄照片或视频");
                                                break;
                                        }
                                    });
                        } else {
                            UiHelper.showConfirmDialog(fragment.getActivity(), "权限申请", "需要获取“读写手机存储”权限，开启后将可以用于图片和视频的保存和上传功能",
                                    (dialog, which) -> {
                                        switch (which) {
                                            case DialogInterface.BUTTON_POSITIVE:
                                                new RxPermissions(fragment.getActivity())
                                                        .request(permissionArray)
                                                        .subscribe(aBoolean -> call.onCall(permissionArray, aBoolean));
                                                break;
                                            case DialogInterface.BUTTON_NEGATIVE:
                                                ToastUtils.showLong("没有权限，无法保存或上传图片和视频");
                                                fragment.getActivity().finish();
                                                break;
                                        }
                                    });
                        }
                    }

                    @Override
                    public boolean hasPermissions(Fragment fragment, String[] permissionArray) {
                        return PermissionsChecker.checkPermissions(fragment.getContext(), permissionArray);
                    }
                })
                .forResult(new OnResultCallbackListener<LocalMedia>() {
                    @Override
                    public void onResult(ArrayList<LocalMedia> result) {
                        if (CollectionHelper.isEmpty(result)) {
                            return;
                        }

                        List<LocalMedia> list = new ArrayList<>();
                        for (LocalMedia media : result) {
                            if (media != null) {
                                list.add(media);
                            }
                        }
                        if (CollectionHelper.isNotEmpty(list)) {
                            if (selectCallBack != null) {
                                selectCallBack.selected(list);
                            }
                        }
                    }

                    @Override
                    public void onCancel() {
                        // 取消
                    }
                });
    }

    public static void addShortVideo(Activity activity, SelectCallBack selectCallBack) {
        File filesDir = new File(mCompressVideoDir);
        if (!filesDir.exists()) {
            filesDir.mkdir();
        }

        PictureSelector.create(activity)
                .openGallery(SelectMimeType.ofVideo())
                .setMaxVideoSelectNum(1)
                .setFilterVideoMinSecond(5)
                .setFilterVideoMaxSecond(60)
                .setMaxSelectNum(1)
                .isPreviewVideo(true)
                .setImageEngine(GlideEngine2.createGlideEngine())
                .forResult(new OnResultCallbackListener<LocalMedia>() {
                    @Override
                    public void onResult(ArrayList<LocalMedia> result) {
                        if (CollectionHelper.isEmpty(result)) {
                            return;
                        }

                        List<LocalMedia> list = new ArrayList<>();
                        for (LocalMedia media : result) {
                            if (media != null) {
                                list.add(media);
                            }
                        }
                        if (CollectionHelper.isNotEmpty(list)) {
                            if (selectCallBack != null) {
                                selectCallBack.selected(list);
                            }
                        }
                    }

                    @Override
                    public void onCancel() {
                        // 取消
                    }
                });
    }

    public static void viewSave2Image(View v, Context context) {
        v.setDrawingCacheEnabled(true);
        v.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
        v.setDrawingCacheBackgroundColor(Color.WHITE);
        int w = v.getWidth();
        int h = v.getHeight();

        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);

//        c.drawColor(Color.WHITE);
        // 如果不设置canvas画布为白色，则生成透明
        v.layout(0, 0, w, h);
        v.draw(c);

        File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath());
        String fileName = "jpg_" + System.currentTimeMillis() + ".jpg";
        FileUtils.createOrExistsDir(dir);
        File imageFile = new File(dir, fileName);
        BitmapUtils.compressBmpToFile(bitmap, imageFile);
        UiHelper.showToast("图片已保存 " + imageFile.getAbsolutePath());
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(),
                    imageFile.getAbsolutePath(), fileName, null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.parse(imageFile.getAbsolutePath())));
        v.destroyDrawingCache();
    }

    private static class ImageFileCropEngine implements CropFileEngine {

        @Override
        public void onStartCrop(Fragment fragment, Uri srcUri, Uri destinationUri, ArrayList<String> dataSource, int requestCode) {
            UCrop.Options options = buildOptions();
            UCrop uCrop = UCrop.of(srcUri, destinationUri, dataSource);
            uCrop.withOptions(options);
            uCrop.setImageEngine(new UCropImageEngine() {
                @Override
                public void loadImage(Context context, String url, ImageView imageView) {
                    Glide.with(context).load(url).override(300, 300).into(imageView);
                }

                @Override
                public void loadImage(Context context, Uri url, int maxWidth, int maxHeight, OnCallbackListener<Bitmap> call) {
                    Glide.with(context).asBitmap().load(url).override(maxWidth, maxHeight).into(new CustomTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            if (call != null) {
                                call.onCall(resource);
                            }
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {
                            if (call != null) {
                                call.onCall(null);
                            }
                        }
                    });
                }
            });
            uCrop.start(fragment.requireActivity(), fragment, requestCode);
        }
    }

    private static UCrop.Options buildOptions() {
        UCrop.Options options = new UCrop.Options();
//        options.setHideBottomControls(!cb_hide.isChecked());
        options.setFreeStyleCropEnabled(true);
//        options.setShowCropFrame(cb_showCropFrame.isChecked());
//        options.setShowCropGrid(cb_showCropGrid.isChecked());
//        options.setCircleDimmedLayer(cb_crop_circular.isChecked());
//        options.withAspectRatio(aspect_ratio_x, aspect_ratio_y);
//        options.setCropOutputPathDir(getSandboxPath());
//        options.isCropDragSmoothToCenter(false);
//        options.setSkipCropMimeType(getNotSupportCrop());
//        options.isForbidCropGifWebp(cb_not_gif.isChecked());
//        options.isForbidSkipMultipleCrop(false);
//        options.setMaxScaleMultiplier(100);
//        if (selectorStyle != null && selectorStyle.getSelectMainStyle().getStatusBarColor() != 0) {
//            SelectMainStyle mainStyle = selectorStyle.getSelectMainStyle();
//            boolean isDarkStatusBarBlack = mainStyle.isDarkStatusBarBlack();
//            int statusBarColor = mainStyle.getStatusBarColor();
//            options.isDarkStatusBarBlack(isDarkStatusBarBlack);
//            if (StyleUtils.checkStyleValidity(statusBarColor)) {
//                options.setStatusBarColor(statusBarColor);
//                options.setToolbarColor(statusBarColor);
//            } else {
//                options.setStatusBarColor(ContextCompat.getColor(getContext(), R.color.ps_color_grey));
//                options.setToolbarColor(ContextCompat.getColor(getContext(), R.color.ps_color_grey));
//            }
//            TitleBarStyle titleBarStyle = selectorStyle.getTitleBarStyle();
//            if (StyleUtils.checkStyleValidity(titleBarStyle.getTitleTextColor())) {
//                options.setToolbarWidgetColor(titleBarStyle.getTitleTextColor());
//            } else {
//                options.setToolbarWidgetColor(ContextCompat.getColor(getContext(), R.color.ps_color_white));
//            }
//        } else {
//            options.setStatusBarColor(ContextCompat.getColor(getContext(), R.color.ps_color_grey));
//            options.setToolbarColor(ContextCompat.getColor(getContext(), R.color.ps_color_grey));
//            options.setToolbarWidgetColor(ContextCompat.getColor(getContext(), R.color.ps_color_white));
//        }
        return options;
    }

    private static class ImageFileCompressEngine implements CompressFileEngine {

        @Override
        public void onStartCompress(Context context, ArrayList<Uri> source, OnKeyValueResultCallbackListener call) {
            Luban.with(context).load(source).ignoreBy(100).setRenameListener(new OnRenameListener() {
                @Override
                public String rename(String filePath) {
                    int indexOf = filePath.lastIndexOf(".");
                    String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg";
                    return DateUtils.getCreateFileName("CMP_") + postfix;
                }
            }).setCompressListener(new OnNewCompressListener() {
                @Override
                public void onStart() {

                }

                @Override
                public void onSuccess(String source, File compressFile) {
                    if (call != null) {
                        call.onCallback(source, compressFile.getAbsolutePath());
                    }
                }

                @Override
                public void onError(String source, Throwable e) {
                    if (call != null) {
                        call.onCallback(source, null);
                    }
                }
            }).launch();
        }
    }
}
